package com.lz.gmall.order.biz.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import java.math.BigDecimal;

import com.lz.gamll.feign.cart.AddCartFeignClient;
import com.lz.gamll.feign.user.UserFeignClient;
import com.lz.gamll.feign.ware.WareFeignClient;
import com.lz.gmall.cart.entity.CartItem;
import com.lz.gmall.common.utils.UserAuthUtil;
import com.lz.gmall.constant.GmallConstant;
import com.lz.gmall.order.biz.OrderBizService;
import com.lz.gmall.order.entity.OrderInfo;
import com.lz.gmall.order.mapper.OrderInfoMapper;
import com.lz.gmall.order.vo.DetailVo;
import com.lz.gmall.order.vo.OrderConfirmVo;
import com.lz.gmall.user.entity.UserAddress;
import javafx.application.ConditionalFeature;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author 郭运龙
 */
@Service
public class OrderBizServiceImpl implements OrderBizService {
    @Autowired
    private AddCartFeignClient addCartFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private WareFeignClient wareFeignClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    /**
     * 通过远程调用其他接口，获取到生成顶单商品的信息
     * @return
     */
    @Override
    public OrderConfirmVo getOrderConfirm() {

        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();

        //获取到请求
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        //创建新的线程执行，异步
        CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
            //这是因为这是启动了一个新的线程进行远程调用，远程调用的拦截器依然生效（拦截器获取请求对象为null）
            //但是获取不到之前的请求，这是因为RequestContextHolder也是采用threadLock，只能在同一个线程内进行共享
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 远程调用service-user获取用户的收获地址
            List<UserAddress> userAddressList = userFeignClient.getAllUserAddress().getData();
            orderConfirmVo.setUserAddressList(userAddressList);
        });
        //创建新的线程执行，异步
        CompletableFuture<Void> cf2 = CompletableFuture.runAsync(() -> {
            //同理
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 远程调用service-order获取购物车商品
            List<CartItem> cartItemList = addCartFeignClient.getCheckedCartItem().getData();

            List<DetailVo> detailVoList = new ArrayList<>();
            for (CartItem cartItem : cartItemList) {
                DetailVo detailVo = new DetailVo();
                detailVo.setImgUrl(cartItem.getImgUrl());
                detailVo.setSkuName(cartItem.getSkuName());
                detailVo.setOrderPrice(cartItem.getSkuPrice());
                detailVo.setSkuNum(cartItem.getSkuNum());
                detailVo.setSkuId(cartItem.getSkuId());

                //远程调用库存系统查看该商品是否有库存
                HashMap<String, String> map = new HashMap<>();
                map.put("skuId",detailVo.getSkuId().toString());
                map.put("num",detailVo.getSkuNum().toString());
                ResponseEntity<String> responseEntity = wareFeignClient.hasStock(map);
                String body = responseEntity.getBody();
                assert body != null;
                detailVo.setHasStock(Integer.valueOf(body));

                detailVoList.add(detailVo);
            }
            orderConfirmVo.setDetailArrayList(detailVoList);

            //计算商品数量总和
            Integer totalNum = cartItemList.stream().map(cartItem -> cartItem.getSkuNum()).reduce(Integer::sum).get();
            orderConfirmVo.setTotalNum(totalNum);

            //计算商品总价格
            BigDecimal totalAmount = cartItemList.stream()
                    .map(cartItem -> cartItem.getSkuPrice().multiply(new BigDecimal(cartItem.getSkuNum())))
                    .reduce(BigDecimal::add).get();
            orderConfirmVo.setTotalAmount(totalAmount);
        });

        CompletableFuture<Void> cf3 = CompletableFuture.runAsync(() -> {
            //糊涂（hutool）工具类
            String tradeNo = IdUtil.simpleUUID();
            orderConfirmVo.setTradeNo(tradeNo);

            //订单号存入redis中，判断订单号是否存在，避免重复提交
            redisTemplate.opsForValue().set(GmallConstant.REDIS_ORDER_CONFIRM_KEY +tradeNo,"x",30, TimeUnit.MINUTES);
        });




        CompletableFuture.allOf(cf1,cf2,cf3).join();

        return orderConfirmVo;
    }

    /**
     * 根据订单id和用户id进行查询
     * 用户id通过透传可以拿到
     * 采用了分库分表，分片键是userId,加上userId查询可以提高效率
     * @param orderId 订单id
     * @return
     */
    @Override
    public OrderInfo getPayOrder(String orderId) {
        String userId = UserAuthUtil.getUserAuthInfo().getUserId();
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInfo::getUserId,Long.parseLong(userId));
        wrapper.eq(OrderInfo::getId,Long.parseLong(orderId));
        return orderInfoMapper.selectOne(wrapper);
    }
}
